package controllers

import dao._
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}
import play.api.routing.JavaScriptReverseRouter
import tool.{FormTool, Tool}
import utils.Utils

import javax.inject.Inject
import scala.concurrent.ExecutionContext.Implicits.global
import implicits.Implicits._
import shared.pojo.App._
import upickle.default._

import scala.concurrent.Future

/** Created by yz on 10/12/2021
  */
class DataController @Inject() (cc: ControllerComponents)(
    implicit val dataDao: DataDao,
    implicit val annoDao: AnnoDao
) extends AbstractController(cc) {

  def toIndex = Action { implicit request =>
    Ok(views.html.data.index())
  }

  def browse = Action { implicit request =>
    Ok(views.html.data.browse())
  }

  def getAll = Action.async { implicit request =>
    dataDao.selectAll.map { x =>
      val array = Utils.getArrayByTs(x)
      Ok(Json.toJson(array))
    }
  }

  def all = Action.async { implicit request =>
    dataDao.selectAll.map { x =>
      val array = x.map(x => writeJs(x))
      Ok(writeJs(array))
    }
  }

  def allRsNumber = Action.async { implicit request =>
    dataDao.selectAllRsNumber.map { x =>
      Ok(writeJs(x))
    }
  }

  def getSelect2Values = Action.async { implicit request =>
    val data = FormTool.keysForm.bindFromRequest().get
    dataDao.selectUniqueValues(data.keys).map { valuess =>
      val vMap = data.keys.zip(valuess).toSeqMap
      Ok(Json.toJson(vMap))
    }
  }

  def detailInfoBefore = Action.async { implicit request =>
    val data = Tool.transformRq.transform(reader[DetailInfo.Request])
    val rsNumberF = if (data.id.nonBlank && data.rsNumber.isBlank) {
      dataDao.selectById(data.id).map(_.snpNumber)
    } else {
      Future { data.rsNumber }
    }
    val idF = if (data.id.isBlank && data.rsNumber.nonBlank) {
      dataDao.selectOp(data.rsNumber).map { xOp =>
        xOp.map(_.id).getOrElse("")
      }
    } else {
      Future { data.id }
    }
    val symbolByIdF = if (data.id.nonBlank) {
      dataDao.selectById(data.id).map(_.gene)
    } else {
      Future {
        ""
      }
    }
    val symbolByRsF = if (data.rsNumber.nonBlank) {
      annoDao.select(data.rsNumber).map { x =>
        x.geneConsequence.mySplit(":").head.trim
      }
    } else {
      Future { "" }
    }
    val symbolF = symbolByIdF.zip(symbolByRsF).map { case (symbolById, symbolByRs) =>
      if (symbolById.nonBlank) {
        symbolById
      } else symbolByRs
    }
    rsNumberF.zip(idF).zip(symbolF).map { case ((rsNumber, id), symbol) =>
      Ok(views.html.data.detailInfo(id, rsNumber, symbol))
    }
  }

  def getById = Action.async { implicit request =>
    val data = Tool.transformRq.transform(reader[IdData])
    dataDao.selectById(data.id).map { x =>
      Ok(writeJs(x))
    }
  }

}
